# -*- coding: utf-8 -*-
"""
HaaS506 DTU - OTA Update Module
Function: Over-The-Air update management with server-side control
Author: HaaS506 Development Team
Version: v1.0.0
"""

import utime as time

import usocket as socket
import ujson
import config
import http
import mod_system
import mod_mqtt

# 配置
# OTA配置将从 config 动态获取

# 全局状态
module_status = "STOPPED"
last_check_time = 0

update_available = False
update_info = {}


def init():
    """初始化OTA模块"""
    global module_status
    module_status = "RUNNING"


def check_update():
    """检查服务器是否有更新"""
    global last_check_time, update_available, update_info

    if module_status != "RUNNING":
        print("[OTA] OTA module not running")
        return False

    try:
        # 从 config 获取OTA服务器配置
        config_data = config.get_config()
        ota_config = config_data.get("servers", {}).get("ota_server", {})
        server_url = ota_config.get(
            "primary_url", "http://dtu.coldwang.com/api/ota/check"
        )
        timeout = ota_config.get("timeout", 30)

        # 解析服务器URL (移除 http:// 前缀)
        if server_url.startswith("http://"):
            server_url = server_url[7:]

        parts = server_url.split("/", 1)
        host = parts[0]
        path = "/" + (parts[1] if len(parts) > 1 else "ota")

        print("[OTA] Checking for updates from: {}{}".format(host, path))

        # 创建HTTP请求
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(timeout)

        try:
            addr = socket.getaddrinfo(host, 80)[0][-1]
            sock.connect(addr)
        except Exception as e:
            print("[OTA] Socket connect error:", e)
            sock.close()
            return False

        # 构建请求，包含当前版本信息和设备编号
        request_data = {
            "action": "check_update",
            "current_version": config.get_config("system.version"),
            "device_sn": config.get_config("device.device_sn"),
            "device_type": config.get_config("system.hardware"),
        }

        print("[OTA] Request data: {}".format(ujson.dumps(request_data)))

        request = "POST {} HTTP/1.1\r\nHost: {}\r\nContent-Type: application/json\r\nConnection: close\r\nContent-Length: {}\r\n\r\n{}".format(
            path, host, len(ujson.dumps(request_data)), ujson.dumps(request_data)
        )

        sock.send(request.encode())

        response = sock.read()
        sock.close()

        # 解析响应
        response_str = response.decode("utf-8", "ignore")

        if "200 OK" not in response_str:
            print(
                "[OTA] Server returned non-200 response, response:{}".format(
                    response_str
                )
            )
            return False

        # 提取JSON数据
        json_start = response_str.find("\r\n\r\n")
        if json_start == -1:
            json_start = response_str.find("\n\n") + 2
        else:
            json_start += 4

        data = ujson.loads(response_str[json_start:])

        # 打印完整响应
        print("[OTA] check update return: {}".format(data))
        mod_mqtt.publish_status(data)

        # 处理服务器响应
        update_available = data.get("update_available", False)
        if update_available:
            update_info = {
                "version": data.get("version", ""),
                "url": data.get("url", ""),
                "type": data.get("type", "python"),  # python 或 firmware
                "description": data.get("description", ""),
            }

            check_info = {
                "action": "update_check_result",
                "update_available": True,
                "new_version": update_info["version"],
                "current_version": config.get_config("system.version"),
            }
            print("[OTA] Update Check: {}".format(ujson.dumps(check_info)))
        else:
            print("[OTA] No updates available")

        last_check_time = time.time()
        return update_available

    except Exception as e:
        print("[OTA] Update check failed: {}".format(e))
        check_info = {
            "action": "update_check_result",
            "error": str(e),
            "current_version": config.get_config("system.version"),
        }
        mod_mqtt.publish_status(check_info)
        return False


def download_and_apply_update():
    """下载并应用更新"""
    global update_available, update_info

    if not update_available or not update_info:
        print("[OTA] No update available to apply")
        return False

    try:
        print("[OTA] Starting update process...")
        print("[OTA] Update info: {}".format(ujson.dumps(update_info)))

        # 创建HTTP客户端
        htp = http.client()

        update_type = update_info.get("type", "python")
        ota_url = update_info.get("url", "")

        if not ota_url:
            print("[OTA] No update URL provided")
            return False

        print("[OTA] Downloading update from: {}".format(ota_url))

        # 根据更新类型选择不同的升级方法
        if update_type == "python":
            # Python脚本升级
            result = htp.fotaPy(ota_url)
        elif update_type == "firmware":
            # 固件升级
            result = htp.fotaSys(ota_url)
        else:
            print("[OTA] Unknown update type: {}".format(update_type))
            return False

        if result == 0:
            print("[OTA] Update download successful, rebooting...")

            # 记录升级信息
            upgrade_info = {
                "action": "ota_upgrade_success",
                "old_version": config.get_config("system.version"),
                "new_version": update_info["version"],
                "type": update_type,
            }
            print("[OTA] Upgrade Success: {}".format(ujson.dumps(upgrade_info)))

            mod_mqtt.publish_status(upgrade_info)
            # 延迟后重启
            time.sleep(2)
            mod_system.restart()
            return True
        else:
            print("[OTA] Update download failed with code: {}".format(result))
            upgrade_info = {
                "action": "ota_upgrade_failed",
                "old_version": config.get_config("system.version"),
                "new_version": update_info["version"],
                "type": update_type,
            }
            print("[OTA] Upgrade Failed: {}".format(ujson.dumps(upgrade_info)))
            mod_mqtt.publish_status(upgrade_info)
            return False

    except Exception as e:
        print("[OTA] Update process failed: {}".format(e))
        return False


def should_check_update():
    """判断是否需要检查更新"""
    if last_check_time == 0:
        return True

    # 从 config 获取检查间隔配置
    config_data = config.get_config()
    ota_config = config_data.get("servers", {}).get("ota_server", {})
    check_interval = ota_config.get("check_interval", 3600)

    time_since_check = time.time() - last_check_time
    return time_since_check >= check_interval


def ota_task():
    """OTA任务 - 供main.py调度使用"""
    try:
        if should_check_update():
            print("[OTA] Performing scheduled update check...")
            if check_update():
                print("[OTA] Update available, starting download...")
                download_and_apply_update()
        else:
            # 静默跳过，避免日志过多
            pass
    except Exception as e:
        print("[OTA] OTA task error: {}".format(e))


def get_module_status():
    """获取模块状态"""
    time_since_check = int(time.time() - last_check_time) if last_check_time > 0 else -1
    return {
        "status": module_status,
        "current_version": config.get_config("system.version"),
        "update_available": update_available,
        "last_check_ago": (
            "{}s".format(time_since_check) if time_since_check >= 0 else "Never"
        ),
    }


# get_module_info function removed - use get_module_status() instead


def cleanup():
    """清理模块"""
    global module_status
    module_status = "STOPPED"
    print("[OTA] OTA module cleanup completed")


def manual_trigger():
    """外部模块如 mod_dispatch 调用的 OTA 强制触发接口"""
    print("[OTA] Manual OTA trigger called...")
    if check_update():
        download_and_apply_update()
